package resparql;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.openrdf.OpenRDFException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.resultio.sparqlxml.SPARQLResultsXMLWriter;
import org.openrdf.query.resultio.text.tsv.SPARQLResultsTSVWriter;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.memory.MemoryStore;

/**
 * 
 * @author therockita
 * 
 */
public class MainClass {

  /**
   * @param args
   * @throws FileNotFoundException 
   */
  public static void main(String[] args) throws FileNotFoundException {
    Long start = null;
    Long end = null;
    
    // String filePath = "./data/SsvParserTest.TMP.n3";
    // Long start = System.currentTimeMillis();
    // // RDFConverter.convertData("./data/lastfm_c25K", "lastfm_c25K");
    // RDFConverter.convertData("./data/lastfm_c1M", "lastfm_c1M");
    // Long end = System.currentTimeMillis();
    //
    // System.out.println(RDFConverter.returnNumberOfProcessedLines()
    // + " processed lines in " + (end - start) + "ms (ca. "
    // + (end - start) / 1000 + " secs).");

    // Here I will load the data into Sesame by creating a repository
    File dataDir = new File("./repository/");
    Repository myRepository = new SailRepository(new MemoryStore(dataDir));
    try {
      myRepository.initialize();

    } catch (RepositoryException e) {
      e.printStackTrace();
    }

    File file = new File("./data/lastfm_c1M.ttl");
    String baseURI = "http://www.example.org/resparql/lastfm";
    
    RepositoryConnection con = null;
    FileOutputStream out = new FileOutputStream("./data/query1.srx");
    FileOutputStream cbFile = new FileOutputStream("./data/content-based.srx");
    FileOutputStream cfFile 
      = new FileOutputStream("./data/collaborative-filter.srx");

    try {
      
      start = System.currentTimeMillis();          
      con = myRepository.getConnection();
      end = System.currentTimeMillis();
      
      System.out.println("Establishing connection with repository in " 
        + (end - start) + "ms (ca. " + (end - start) / 1000 + " secs).");
      
      try {
        //Triples are added to the repository.
        start = System.currentTimeMillis();          
        con.add(file, baseURI, RDFFormat.TURTLE);
        end = System.currentTimeMillis();        
        System.out.println("Loading triples to repository in " 
            + (end - start) + "ms (ca. " + (end - start) / 1000 + " secs).");

        //A SPARQL query.
        SPARQLResultsXMLWriter sparqlWriter = new SPARQLResultsXMLWriter(out);
        String queryString = "RECOMMEND ?s ?o WHERE {?s ?p ?o}";
        
        start = System.currentTimeMillis();          
        TupleQuery tupleQuery = 
            con.prepareTupleQuery(QueryLanguage.RESPARQL, queryString);
        end = System.currentTimeMillis();
        System.out.println("Parsing QUERY 1 and preparing in " 
            + (end - start) + "ms (ca. " + (end - start) / 1000 + " secs).");
        
        start = System.currentTimeMillis();          
        tupleQuery.evaluate(sparqlWriter);
        end = System.currentTimeMillis();
        System.out.println("Evaluating query in " 
            + (end - start) + "ms (ca. " + (end - start) / 1000 + " secs).\n");

//        TupleQueryResult result = tupleQuery.evaluate();
        
        //CONTENT-BASED Recommendation
        SPARQLResultsTSVWriter tsvWriter = new SPARQLResultsTSVWriter(cbFile);
        queryString = "PREFIX lastfm:<http://www.example.org/resparql/lastfm#>"
          + "PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>" 
          +  "SELECT ?user ?recomTrack "
          +  "WHERE {?user lastfm:userTopTracks ?track . "
          +  "?track lastfm:trackSimilar ?recomTrack}";
        
        start = System.currentTimeMillis();          
        tupleQuery = con.prepareTupleQuery(QueryLanguage.RESPARQL, queryString);
        end = System.currentTimeMillis();
        System.out.println("Parsing Content-Based QUERY and preparing in " 
            + (end - start) + "ms (ca. " + (end - start) / 1000 + " secs).");
        
        start = System.currentTimeMillis();          
        tupleQuery.evaluate(tsvWriter);
        end = System.currentTimeMillis();
        System.out.println("Evaluating Content-Based QUERY in " 
            + (end - start) + "ms (ca. " + (end - start) / 1000 + " secs).\n");
        
        
        //COLLABORATIVE-FILTER Recommendation
        tsvWriter = new SPARQLResultsTSVWriter(cfFile);
        queryString = "PREFIX lastfm:<http://www.example.org/resparql/lastfm#>"
          + "PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>" 
          +  "SELECT ?user1 ?recomTrack "
          +  "WHERE {?user1 lastfm:userKnows ?user2 ."
          +  "?user1 lastfm:userTopTracks ?track1 ."
          +  "?user2 lastfm:userTopTracks ?track1 ."
          +  "?user2 lastfm:userTopTracks ?recomTrack ."
          +  "FILTER NOT EXISTS { ?user1 lastfm:userListenedTo ?recomTrack }}";
        
        start = System.currentTimeMillis();          
        tupleQuery = con.prepareTupleQuery(QueryLanguage.RESPARQL, queryString);
        end = System.currentTimeMillis();
        System.out.println("Parsing Collaborative-Fil. QUERY and preparing in " 
            + (end - start) + "ms (ca. " + (end - start) / 1000 + " secs).");
        
        start = System.currentTimeMillis();          
        tupleQuery.evaluate(tsvWriter);
        end = System.currentTimeMillis();
        System.out.println("Evaluating Collaborative-Fil. QUERY in " 
            + (end - start) + "ms (ca. " + (end - start) / 1000 + " secs).\n");
        
//        if (tupleQuery instanceof SailTupleQuery) {
//          System.out.println("tupleQuery instanceof SailTupleQuery");
//        } else {
//          System.out.println("tupleQuery IS NOT instanceof SailTupleQuery");
//        }
//        TupleQueryResultImpl resultImpl = (TupleQueryResultImpl) result;
        
//        System.out.println(result.getBindingNames());              
        
      } finally {
        con.close();
      }
    } catch (OpenRDFException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }

  }
}
